using System;
using System.Linq.Expressions;

namespace FwkLight.Domain.Fetching
{
  public interface IMultiCriteriaFetcher<EntityType>
  {
    IMultiCriteriaFetcher<EntityType> FilterBy<R, M>(Expression<Func<EntityType, R>> property, Expression<Func<R, M>> propertyIdentifier, M value);
    IMultiCriteriaFetcher<EntityType> FilterComponentBy<R, M>(Expression<Func<EntityType, R>> component, Expression<Func<R, M>> componentProperty, M value);
    IMultiCriteriaFetcher<EntityType> FilterBy<R>(Expression<Func<EntityType, R>> property, R value);
    IMultiCriteriaFetcher<EntityType> FilterBy(IFullSpecification<EntityType> spec);
    IMultiCriteriaFetcher<EntityType> WhereRootIs(IFullSpecification<EntityType> spec);
		IMultiCriteriaFetcher<EntityType> WhereRootIs<Param1>(IFullSpecification<EntityType, Param1> spec, Param1 param1);
    IMultiCriteriaFetcher<EntityType> WhereRootIs<Param1, Param2>(IFullSpecification<EntityType, Param1, Param2> spec, Param1 param1, Param2 param2);
    IMultiCriteriaFetcher<EntityType> WhereRootIs<Param1, Param2, Param3>(IFullSpecification<EntityType, Param1, Param2, Param3> spec, Param1 param1, Param2 param2, Param3 param3);
    IMultiCriteriaFetcher<EntityType> WhereRootIs<Param1, Param2, Param3, Param4>(IFullSpecification<EntityType, Param1, Param2, Param3, Param4> spec, Param1 param1, Param2 param2, Param3 param3, Param4 param4);
		IMultiCriteriaFetcher<EntityType> WhereRootCanBe(IFullSpecification<EntityType> spec);
		IMultiCriteriaFetcher<EntityType> WhereRootCanBe<Param1>(IFullSpecification<EntityType, Param1> spec, Param1 param1);
    IMultiCriteriaFetcher<EntityType> WhereRootCanBe<Param1, Param2>(IFullSpecification<EntityType, Param1, Param2> spec, Param1 param1, Param2 param2);
    IMultiCriteriaFetcher<EntityType> WhereRootCanBe<Param1, Param2, Param3>(IFullSpecification<EntityType, Param1, Param2, Param3> spec, Param1 param1, Param2 param2, Param3 param3);
    IMultiCriteriaFetcher<EntityType> WhereRootCanBe<Param1, Param2, Param3, Param4>(IFullSpecification<EntityType, Param1, Param2, Param3, Param4> spec, Param1 param1, Param2 param2, Param3 param3, Param4 param4);
    IFetchingPart<EntityType> InitFetchingHierarchy(string rootAlias);
    IFetchingPart<EntityType> InitFetchingHierarchy();
    IWaitForFilter<EntityType, R> Where<R>(Expression<Func<EntityType, R>> expression);
    IWaitForFilter<EntityType, R> And<R>(Expression<Func<EntityType, R>> expression);
    IWaitForFilter<EntityType, R> And<R>(string propertyName);
    IMultiCriteriaFetcher<EntityType> OrderAscBy<R>(Expression<Func<EntityType, R>> expression);
    IMultiCriteriaFetcher<EntityType> OrderDescBy<R>(Expression<Func<EntityType, R>> expression);
    void ResetChangesCount();
    int ChangesCount { get; }
  }
}